﻿#include<stdio.h>

//1.模拟实现strncpy  char * strncpy ( char * destination, const char * source, size_t num );
//char* my_strncpy(char* dest, const char* src, size_t num) {
//	char* p = dest;  
//    int count = (int)num;
//	while (*src&&count) { //当复制的元素足够num个的时候 跳出循环   当src指向的元素为'\0'也要跳出循环。
//		*dest++ = *src++;
//		count--;
//	}
//	//如果src中字符的个数足够，不用追加'\0'
//	if (count != 0) {
//		while (count) {
//			*dest++ = '\0';
//			count--;
//		}
//	}
//	return p;
//}
//int main() {
//	char arr1[20] = "abcdefgh";
//	char arr2[20] = "asdfghjkl";
//	char* p1 = my_strncpy(arr1, "12345", 4);
//	char* p2 = my_strncpy(arr2, "12345", 7);
//	printf("%s\n%s\n", p1, p2); 
//	return 0;
//}

//2.模拟实现strncat  char * strncat ( char * destination, const char * source, size_t num );
//将source指向字符串的前num个字符追加到destination指向的字符串末尾，再追加⼀个 \0 字符
//如果source 指向的字符串的⻓度⼩于num的时候，只会将字符串中到\0 的内容追加到destination指向的字符串末尾
//char* my_strncat(char* dest, const char* src, size_t num) {
//	char* p = dest;
//	while (*dest) {
//		dest++;
//	}
//	//此时dest指针指向的就是'\0'这个元素，然后就可以让src开始追加了
//	int count = (int)num;
//	while (count&&*src) {
//		*dest++ = *src++;
//		count--;
//	}//如果src中的字符是够追加的 这个循环就能跳出来 且count==0
//	//如果是不够的情况下，那么当src指向'\0'的时候就应该跳出循环
//	if (*src == '\0') {
//		*dest = *src;
//	}
//	return p;
//}
//int main() {
//	char arr1[20] = "abcdefgh";
//	char arr2[20] = "asdfghjkl";
//	char* p1 = my_strncat(arr1, "12345", 4);
//	char* p2 = my_strncat(arr2, "12345", 7);
//	printf("%s\n%s\n", p1, p2);
//	return 0;
//}

//3.模拟实现memcpy  void * memcpy ( void * destination, const void * source, size_t num );
//函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。
//这个函数在遇到 '\0' 的时候并不会停下来。
//如果source和destination有任何的重叠，复制的结果都是未定义的。
//void* my_memcpy(void* dest, const void* src, size_t num) {
//	void* p = dest;
//	int count = (int)num;
//	while (count) {
//		*((char*)dest) = *((char*)src);
//		dest = (char*)dest + 1;
//		src = (char*)src + 1;
//		count--;
//	}
//	return p;
//}
//int main() {
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int arr_1[10] = { 0x11223344, 0x11223344 ,0x11223344, 0x11223344, 0x11223344, 0x11223344, 0x11223344, 0x11223344 ,0x11223344 ,0x11223344 };
//	char arr1[20] = "abcdefg";
//	int* p = (int*)my_memcpy(arr, arr_1, 17);
//	char* q = (char*)my_memcpy(arr1, "12345", 5);
//	printf("%s\n", q);
//	for (int i = 0; i < 10; i++) {
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//    return 0;
//}

//4.模拟实现 memmove void * memmove ( void * destination, const void * source, size_t num );
//和memcpy的差别就是memmove函数处理的源内存块和⽬标内存块是可以重叠的。
//如果源空间和⽬标空间出现重叠，就得使⽤memmove函数处理。
//void* my_memmove(void* dest, const void* src, size_t num) {
//	//src指向的位置到src+num指针指向的位置之间是:赋值的源区
//	//dest到dest+num之间的位置是被赋值的区域
//	
//	//当dest的地址小于src时，dest无论如何都追不上src，可以正常赋值
//	//当dest在源区内的时候，如果使用像memcpy的方法赋值，会发现无法达到想要的效果，但是发现如果从后往前是可以的
//	//当dest在源区的右侧时候，即dest>=src+num时，从前往后，从后往前都可以
//	void* p = dest;
//	int count = (int)num;
//	if (dest < src) {
//		while (count) {
//		    *((char*)dest) = *((char*)src);
//		    dest = (char*)dest + 1;
//			src = (char*)src + 1;
//			count--;
//		}
//	}
//	else {
//		while (count--) {
//			*((char*)dest + count) = *((char*)src + count);
//		}
//	}
//	return p;
//}
//int main() {
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	char arr1[20] = "abcdefg1234567";
//	int* p = (int*)my_memmove(arr, arr+3, 17); 
//	char* q = (char*)my_memmove(arr1,arr1+5, 5);
//	printf("%s\n", q);
//	for (int i = 0; i < 10; i++) {
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//    return 0;
//}

//5.模拟实现strncmp
//int my_strncmp(const char* str1, const char* str2, size_t num) {
//	int count = (int)num;
//	while (count&&(*str1==*str2)) {
//		str1++;
//		str2++;
//		count--;
//	}
//	if (count == 0) {
//		return 0;
//	}
//	else {
//		return *str1 - *str2;
//	}
//}
//int main() {
//	char* p1 = "abcdesa";
//	char* p2 = "abcde123";
//	char* p3 = "a";
//	int ret = my_strncmp(p1, p2, 5);
//	printf("%d\n", ret);
//	int ret = my_strncmp(p1, p2, 8);
//	printf("%d\n", ret);
//	int ret = my_strncmp(p1, p3, 5);
//	printf("%d\n", ret);
//	return 0;
//}